﻿using FastApi.Attributes;
using Microsoft.Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FastApi
{
    internal class FastHttp : IFastHttp
    {
        private readonly IOwinContext context;

        private IFormCollection form;

        public FastHttp(FastContext fastCtx, Dictionary<string, object> userData)
        {
            context = fastCtx.HttpContext;
            form = fastCtx.Form;
            UserData = userData;
        }

        public Dictionary<string, object> UserData { get; }

        public ICollection<string> GetHeaderKeys()
        {
            return context.Request.Headers.Keys;
        }

        public string GetHeader(string key)
        {
            return context.Request.Headers[key];
        }

        public void SetHeader(string key, string value)
        {
            context.Response.Headers[key] = value;
        }

        public IEnumerable<string> GetQueryKeys()
        {
            return context.Request.Query.Select(s => s.Key);
        }

        public string GetQuery(string key)
        {
            return context.Request.Query[key];
        }

        public IEnumerable<string> GetFormKeys()
        {
            return form.Select(s => s.Key);
        }

        public string GetForm(string key)
        {
            return form[key];
        }

        public IEnumerable<string> GetCookieKeys()
        {
            return context.Request.Cookies.Select(s => s.Key);
        }

        public string GetCookie(string key)
        {
            return context.Request.Cookies[key];
        }

        public void SetCookie(string key, string value)
        {
            context.Response.Cookies.Append(key, value);
        }

        public void SetCookie(string key, string value, DateTimeOffset expires)
        {
            context.Response.Cookies.Append(key, value, new CookieOptions
            {
                Expires = expires.DateTime
            });
        }

        public async Task WriteFileAsync(string path, string name = null)
        {
            await context.Response.WriteFileAsync(path, name);
        }

        public async Task WriteFileAsync(byte[] bytes, string name = null)
        {
            await context.Response.WriteFileAsync(bytes, name);
        }

        public void Redirect(string url)
        {
            context.Response.Redirect(url);
        }

        public async Task<FastFile> GetFileAsync(string name)
        {
            throw new NotImplementedException();
        }

        public async Task<List<FastFile>> GetFileListAsync()
        {
            throw new NotImplementedException();
        }

        public T QueryBind<T>()
        {
            return context.Request.Query.BindModel<T>();
        }

        public void QueryBindTo(object model)
        {
            context.Request.Query.BindToModel(model);
        }

        public T FormBind<T>()
        {
            return form.BindModel<T>();
        }

        public void FormBindTo(object model)
        {
            form.BindToModel(model);
        }

        public int GetFileCount()
        {
            throw new NotImplementedException();
        }

        public Task<FastFile> GetFileAsync(int index)
        {
            throw new NotImplementedException();
        }

        public string GetFileName(string name)
        {
            throw new NotImplementedException();
        }

        public Task SaveFileAsync(string name, string path)
        {
            throw new NotImplementedException();
        }

        public Task SaveFileAsync(int index, string path)
        {
            throw new NotImplementedException();
        }

        public long GetFileLength(string name)
        {
            throw new NotImplementedException();
        }

        public long GetFileLength(int index)
        {
            throw new NotImplementedException();
        }

        public string GetFileName(int index)
        {
            throw new NotImplementedException();
        }

        public string GetIpv4()
        {
            throw new NotImplementedException();
        }

        public string GetIpv4ByHeader(string header = "X-Forwarded-For")
        {
            throw new NotImplementedException();
        }
    }
}
